'''
Created on 21-Jul-2010

@author: dexen
'''
#cross product formula = (a2*b3-a3*b2, a3*b1-a1*b3, a1*b2-a2*b1)

#assuming that the list of points are coming in a continuous manner, we can use this function to check if the polygon is
#convex or concave , convex = True concave = False

def convex(point_list):
    #get the vectors of the edge 
    edge_list = []
    for counter in range(len(point_list)):
        if counter < len(point_list)-1:
            edge = ( point_list[counter][0]- point_list[counter+1][0], point_list[counter][1]- point_list[counter+1][1],
                     point_list[counter][2]- point_list[counter+1][2] )
        else:
            edge = ( point_list[counter][0]- point_list[0][0], point_list[counter][1]- point_list[0][1],
                     point_list[counter][2]- point_list[0][2] )
        edge_list.append(edge)
    #get the cross_product of all the edges     
    x_product_list = []
    for counter in range(len(edge_list)):
        if counter < len(edge_list)-1:
            x_product_x = (edge_list[counter][1]* edge_list[counter+1][2])-(edge_list[counter][2]* edge_list[counter+1][1])
            x_product_y = (edge_list[counter][2]* edge_list[counter+1][0])-(edge_list[counter][0]* edge_list[counter+1][2])
            x_product_z = (edge_list[counter][0]* edge_list[counter+1][1])-(edge_list[counter][1]* edge_list[counter+1][0])
            
        else:
            x_product_x = (edge_list[counter][1]* edge_list[0][2])-(edge_list[counter][2]* edge_list[0][1])
            x_product_y = (edge_list[counter][2]* edge_list[0][0])-(edge_list[counter][0]* edge_list[0][2])
            x_product_z = (edge_list[counter][0]* edge_list[0][1])-(edge_list[counter][1]* edge_list[0][0])
        x_product = (x_product_x, x_product_y, x_product_z)
        x_product_list.append(x_product)
    #check if the surface is convex or concave by simplifying the vectors to positive or negative
    vector_list = []
    for product in x_product_list:
        vector_list.append([])
        for counter in range(len(product)):
            if product[counter] == 0:
                vector_list[-1].append(0)
            if product[counter] < 0:
                vector_list[-1].append(-1)
            if product[counter] > 0:
                vector_list[-1].append(1)
                
    #check if all of the vectors are the same             
    result = []     
    for num_vector in range(len(vector_list)):
        if num_vector <= len(vector_list)-2:
            #everytime when there are similar vectors 1 == similar 0 == different
            if vector_list[0] == vector_list[num_vector+1]:
                result.append(1)
            else:
                result.append(0)
    #construct the convex scenario, where all the vectors shld be the same so all 1
    convex = [] 
    for _ in range(len(vector_list)-1):
        convex.append(1)
    #check if the result is concave or convex
    if result == convex:
        return True, vector_list
    else:
        return False, x_product_list

#assuming that the list of points are coming in a continuous manner, we can use this function to check if the points are
#ordered in clockwise or counter-clockwise

def anticlockwise(point_list,normal):
    normal_list = []
    for counter in range(3):
        if normal[counter] == 0:
            normal_list.append(0)
        if normal[counter] < 0:
            normal_list.append(-1)
        if normal[counter] > 0:
            normal_list.append(1)
            
    if convex(point_list)[0] == True:
        #if vertexes are arraged in a conterclockwise manner 
        if convex(point_list)[1][0] == normal_list:
            
            return point_list 
        else:
            point_list.reverse()
            
            return point_list
            
    if convex(point_list)[0] == False:
        x_product_list = []
        for counter in range(len(point_list)):
            if counter < len(point_list)-1:
                x_product_x = (point_list[counter][1]* point_list[counter+1][2])-(point_list[counter][2]* point_list[counter+1][1])
                x_product_y = (point_list[counter][2]* point_list[counter+1][0])-(point_list[counter][0]* point_list[counter+1][2])
                x_product_z = (point_list[counter][0]* point_list[counter+1][1])-(point_list[counter][1]* point_list[counter+1][0])
                
            else:
                x_product_x = (point_list[counter][1]* point_list[0][2])-(point_list[counter][2]* point_list[0][1])
                x_product_y = (point_list[counter][2]* point_list[0][0])-(point_list[counter][0]* point_list[0][2])
                x_product_z = (point_list[counter][0]* point_list[0][1])-(point_list[counter][1]* point_list[0][0])
            x_product = (x_product_x, x_product_y, x_product_z)
            x_product_list.append(x_product)
        x_product_x = 0
        x_product_y = 0
        x_product_z = 0

        for counter in range(len(x_product_list)):
            x_product_x = x_product_x + x_product_list[counter][0]
            x_product_y = x_product_y + x_product_list[counter][1]
            x_product_z = x_product_z + x_product_list[counter][2]
                
            sum_x_product = (x_product_x, x_product_y, x_product_z)
            #print sum_x_product
        area = ((sum_x_product[0]*normal[0]) + (sum_x_product[1]*normal[1]) + (sum_x_product[2]*normal[2]))/2
        if area > 0 :
            return point_list
        if area < 0 :
            point_list.reverse()
            return point_list
    

"""
#normal = (0,1,0)
normal = (3.7060809408112764e-17, 0.928477,  -0.371391)
#point_list = [(0, 0, 0), (7.5, 0, -10), (15, 0, 0), (7.5, 0, 2.5), (15, 0, 5), (0, 0, 5)]
#point_list = [(0,0,5), (15,0,5),(0,0,0)]
point_list = [(0,0,0), (15,0,0), (7.5,1,2.5),(15,2,5),(0,2,5)]
anti_clockwise(point_list,normal)
"""

